﻿using System;
using System.Text;

namespace BizElements.Generator
{
    /// <summary>Provides methods which convert input strings using various conventions, such as pascal and camel case.</summary>
    static class NamingConventionHelper
    {
        #region ToCamelCase

        /// <summary>Converts input string using camel case convention.</summary>
        /// <param name="name">Item mapped to class member.</param>
        /// <returns>Name in camel case.</returns>
        public static string ToCamelCase(string name)
        {
            string noSpaces = ReplaceSpacesWithUnderscores(name);
            // If all letters are capital then convert them to lower case. Eg: "ID_COUNTRY" -> "id_country".
            if (HasOnlyCapitalLetters(noSpaces))
                noSpaces = name.ToLower();

            StringBuilder output = new StringBuilder(noSpaces);
            ConvertLettersAfterUnderscoresToUppercase(output);
            RemoveAllUnderscores(output);
            EnsureFirstCharIsLower(output);
            return output.ToString();
        }

        #endregion

        #region ToPascalCase.

        /// <summary>Converts input string using pascal case convention.</summary>
        /// <param name="name">Item mapped to class member.</param>
        /// <returns>Name in pascal case.</returns>
        public static string ToPascalCase(string name)
        {
            StringBuilder output = new StringBuilder(ToCamelCase(name));
            EnsureFirstCharIsUpper(output);
            return output.ToString();
        }

        #endregion

        #region Text manipulation utility methods.

        private static string ReplaceSpacesWithUnderscores(string item)
        {
            return item.Replace(" ", "_");
        }

        private static bool HasOnlyCapitalLetters(string text)
        {
            for (int i = 0; i < text.Length; i++)
            {
                if (char.IsLower(text[i]))
                    return false;
            }

            return true;
        }

        private static void ConvertLettersAfterUnderscoresToUppercase(StringBuilder variableName)
        {
            // Convert letters after the underscore character to uppercase.
            // Eg: "id_country" -> "id_Country".			
            for (int i = 0; i < variableName.Length - 1; i++)
            {
                if (variableName[i] == '_')
                    variableName[i + 1] = char.ToUpper(variableName[i + 1]);
            }
        }

        private static void RemoveAllUnderscores(StringBuilder variableName)
        {
            variableName.Replace("_", "");
        }

        private static void EnsureFirstCharIsLower(StringBuilder variableName)
        {
            variableName[0] = char.ToLower(variableName[0]);
        }

        private static void EnsureFirstCharIsUpper(StringBuilder variableName)
        {
            variableName[0] = char.ToUpper(variableName[0]);
        }

        #endregion
    }
}